package org.chs.ts.batch.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.chs.ts.base.batch.exec.entity.BatchClearBasicTaskStepExec;
import org.chs.ts.batch.mapper.BatchClearBasicTaskStepExecMapper;
import org.chs.ts.batch.service.IBatchClearBasicTaskStepExecService;
import org.chs.ts.batch.util.ConvertToUtil;
import org.chs.ts.batch.util.RedisBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @Description: batch_clear_basic_task_step_exec
 * @Author: jeecg-boot
 * @Date: 2024-04-09
 * @Version: V1.0
 */
@Service
@Slf4j
public class BatchClearBasicTaskStepExecServiceImpl extends ServiceImpl<BatchClearBasicTaskStepExecMapper, BatchClearBasicTaskStepExec> implements IBatchClearBasicTaskStepExecService {


    private final String CLASS_NAME = this.getClass().getSimpleName();

    @Resource
    RedisBuilder redisBuilder;

    private final String UPDATE_KEY = "UpdateTaskStepExec";

    private final int updateCount = 3;
    @Resource
    BatchClearBasicTaskStepExecMapper clearBasicTaskStepExecMapper;


    @Override
    public void updateTaskStepExecForInit(String batchSysCode, String taskGroup, String taskId, String execDate) {

        int i = 0;
        do {
            //获取数据更新锁
            if (redisBuilder.checkUpdateRedisLock(UPDATE_KEY + batchSysCode + "_" + taskGroup + "_" + taskId + "_" + execDate)) {
                log.info(CLASS_NAME + "updateTaskStepExecForInit method: batchSysCode:" + batchSysCode + "taskGroup:" + taskGroup + " taskId:" + taskId + " execDate:" + execDate);
                clearBasicTaskStepExecMapper.updateTaskStepExecForInit(batchSysCode, taskGroup, taskId, execDate);
                redisBuilder.unUpdateRedisLock(UPDATE_KEY + batchSysCode + "_" + taskGroup + "_" + taskId + "_" + execDate);
                break;
            }
            redisBuilder.sleepThread();

            i++;
        } while (i < updateCount);

        if (i == updateCount) {
            log.info(CLASS_NAME + "updateTaskStepExecForInit method: batchSysCode:" + batchSysCode + "taskGroup:" + taskGroup + " taskId:" + taskId + " execDate:" + execDate + " 更新失败存在数据库redis更新锁");
        }
        //return updateResult;

    }

    @Override
    public boolean updateTaskStepByObj(String taskExecId, String serverIP, String serverName, String startTime, String endTime, String rtnCode, String execStatus) {
        boolean updateResult = false;

        // 因存在 数据库死锁风险 故 增加 redis更新锁
        int i = 0;
        LambdaQueryWrapper<BatchClearBasicTaskStepExec> queryWrapper = new LambdaQueryWrapper<BatchClearBasicTaskStepExec>()
                .eq(BatchClearBasicTaskStepExec::getTaskExecid, taskExecId)
                .eq(BatchClearBasicTaskStepExec::getServerIp, serverIP)
                .eq(BatchClearBasicTaskStepExec::getServerName, serverName)
                .eq(BatchClearBasicTaskStepExec::getStartTime, startTime)
                .eq(BatchClearBasicTaskStepExec::getEndTime, endTime)
                .eq(BatchClearBasicTaskStepExec::getRtnCode, rtnCode)
                .eq(BatchClearBasicTaskStepExec::getExecStatus, execStatus);
        do {
            // 获取数据更新锁
            if (redisBuilder.checkUpdateRedisLock(UPDATE_KEY + taskExecId)) {
                log.info(CLASS_NAME + "updateTaskStepByObj method: taskExecId:" + taskExecId + " serverIP:" + serverIP + " serverName:" + serverName + " startTime:" + startTime + " endTime:" + endTime + " rtnCode:" + rtnCode + " execStatus:" + execStatus);
                clearBasicTaskStepExecMapper.updateTaskStepByObj(taskExecId, Strings.isBlank(serverIP) ? serverIP : "", Strings.isBlank(serverName) ? serverName : "", Strings.isBlank(startTime) ? startTime : "", Strings.isBlank(endTime) ? endTime : "", rtnCode, execStatus);
                redisBuilder.unUpdateRedisLock(UPDATE_KEY + taskExecId);
                updateResult = true;
                break;
            }

            // 获取数据库更新锁失败 确认数据是否已更新
            if (clearBasicTaskStepExecMapper.selectCount(queryWrapper) > 0) {
                log.info(CLASS_NAME + "updateTaskStepByObj method: taskExecId:" + taskExecId + "已更新具体参数如下 [serverIP:" + serverIP + " serverName:" + serverName + " startTime:" + startTime + " endTime:" + endTime + " rtnCode:" + rtnCode + " execStatus:" + execStatus + "]");
                break;
            }
            redisBuilder.sleepThread();

            i++;
        } while (i < updateCount);

        if (i == updateCount) {
            log.info(CLASS_NAME + "updateTaskStepByObj method: taskExecId:" + taskExecId + "更新失败存在数据库redis更新锁 具体参数如下[serverIP:" + serverIP + " serverName:" + serverName + " startTime:" + startTime + " endTime:" + endTime + " rtnCode:" + rtnCode + " execStatus:" + execStatus + "]");

        }

        return updateResult;
    }

    @Override
    public boolean removeBatch(List<BatchClearBasicTaskStepExec> taskSteplist) {
        return clearBasicTaskStepExecMapper.deleteBatchIds(taskSteplist) > 0;
        //return false;
    }

    @Override
    public boolean saveBatchs(Collection<BatchClearBasicTaskStepExec> clearBasicTaskStepExecsList) {
        boolean result = false;
        List<BatchClearBasicTaskStepExec> rollbackList = new ArrayList<>();
        String ENTITY_NAME = "BatchClearBasicTaskStepExec";
        for (BatchClearBasicTaskStepExec item : clearBasicTaskStepExecsList) {
            result = clearBasicTaskStepExecMapper.insert(item) > 0;

            if (!result) {
                log.info(CLASS_NAME + " -> saveBatchs insert " + ENTITY_NAME + " exception:" + ENTITY_NAME + " -> " + ConvertToUtil.printObjectInfo(item, new ArrayList<>()));
                continue;
            }

            rollbackList.add(item);

        }

        if (!result) {
            log.info(CLASS_NAME + " -> saveBatchs rollabck ");
            for (BatchClearBasicTaskStepExec item : rollbackList) {
                if (clearBasicTaskStepExecMapper.deleteById(item) <= 0) {
                    log.info(CLASS_NAME + " -> saveBatchs rollback " + ENTITY_NAME + " exception:" + ENTITY_NAME + " -> " + ConvertToUtil.printObjectInfo(item, new ArrayList<>()));
                }
            }
        }

        return result;
    }
}
